using System.Net.Sockets;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;

namespace WpfApp_ChenxiConsole.TCP
{
    /// <summary>
    /// TcpServerConsoleControl.xaml 的交互逻辑
    /// </summary>
    public partial class TcpServerConsoleControl : UserControl
    {
        // 服务器端管理器（可后续扩展）
    private readonly TcpServerManager? tcpServerManager;
    private bool showTimestamp = false;
    private Paragraph? currentParagraph = null;
    // 记录当前已连接客户端
    private readonly List<string> connectedClients = [];

        public TcpServerConsoleControl()
        {
            InitializeComponent();
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            // 初始化服务器管理器
            tcpServerManager = new TcpServerManager(
                Dispatcher,
                AppendTextToRecvTextBox,
                OnClientConnected,
                OnClientDisconnected,
                (brush) => { /* 可扩展：服务器状态指示器 */ }
            );
        }

        private void StartServerButton_Click(object sender, RoutedEventArgs e)
        {
            if (tcpServerManager == null) return;
            if (!int.TryParse(PortTextBox.Text, out int port) || port < 1 || port > 65535)
            {
                MessageBox.Show("请输入有效的端口号 (1-65535)", "端口错误", MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }
            StartServerBtn.IsEnabled = false;
            Task.Run(async () =>
            {
                bool started = await tcpServerManager.StartAsync(port);
                Dispatcher.Invoke(() =>
                {
                    if (started)
                    {
                        AppendTextToRecvTextBox($"服务器已启动，监听端口 {port}", "连接");
                        StopServerBtn.IsEnabled = true;
                        PortTextBox.IsEnabled = false;
                    }
                    else
                    {
                        AppendTextToRecvTextBox($"服务器启动失败", "错误");
                        StartServerBtn.IsEnabled = true;
                    }
                });
            });
        }

        private void StopServerButton_Click(object sender, RoutedEventArgs e)
        {
            if (tcpServerManager == null) return;
            tcpServerManager.Stop();
            AppendTextToRecvTextBox("服务器已停止", "断开");
            StartServerBtn.IsEnabled = true;
            StopServerBtn.IsEnabled = false;
            PortTextBox.IsEnabled = true;
            connectedClients.Clear();
            ClientListView.ItemsSource = null;
        }

        private void AppendTextToRecvTextBox(string text, string messageType = "")
        {
            if (Dispatcher.CheckAccess())
            {
                SolidColorBrush textBrush = Brushes.Black;
                if (messageType == "发>> ")
                {
                    textBrush = new SolidColorBrush(Color.FromRgb(0, 120, 215));
                }
                else if (messageType == "错误")
                {
                    textBrush = Brushes.Red;
                }
                else if (messageType == "连接" || messageType == "断开")
                {
                    textBrush = Brushes.Green;
                }

                if (showTimestamp)
                {
                    Paragraph paragraph = new() { LineHeight = 1.05 };
                    RecvTextBox.Document.Blocks.Add(paragraph);
                    if (!string.IsNullOrEmpty(messageType))
                    {
                        string timestamp = DateTime.Now.ToString("HH:mm:ss.fff");
                        Run timestampRun = new($"[{timestamp}]{messageType}")
                        {
                            Foreground = Brushes.Gray
                        };
                        paragraph.Inlines.Add(timestampRun);
                    }
                    Run contentRun = new(text)
                    {
                        Foreground = textBrush
                    };
                    paragraph.Inlines.Add(contentRun);
                }
                else
                {
                    if (currentParagraph == null)
                    {
                        currentParagraph = new Paragraph() { LineHeight = 1.05 };
                        RecvTextBox.Document.Blocks.Add(currentParagraph);
                    }
                    Run contentRun = new(text)
                    {
                        Foreground = textBrush
                    };
                    currentParagraph.Inlines.Add(contentRun);
                }
                RecvTextBox.ScrollToEnd();
            }
            else
            {
                Dispatcher.Invoke(() => AppendTextToRecvTextBox(text, messageType));
            }
        }

        // 客户端连接回调
        private void OnClientConnected(string clientInfo)
        {
            connectedClients.Add(clientInfo);
            ClientListView.ItemsSource = null;
            ClientListView.ItemsSource = connectedClients.ToList();
            AppendTextToRecvTextBox($"客户端已连接: {clientInfo}", "连接");
        }

        // 客户端断开回调
        private void OnClientDisconnected(string clientInfo)
        {
            connectedClients.Remove(clientInfo);
            ClientListView.ItemsSource = null;
            ClientListView.ItemsSource = connectedClients.ToList();
            AppendTextToRecvTextBox($"客户端断开: {clientInfo}", "断开");
        }

        private void TimestampCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            showTimestamp = true;
            currentParagraph = null;
        }

        private void TimestampCheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            showTimestamp = false;
            if (RecvTextBox.Document.Blocks.Count == 0 || currentParagraph == null)
            {
                currentParagraph = new Paragraph() { LineHeight = 1.05 };
                RecvTextBox.Document.Blocks.Add(currentParagraph);
            }
        }

        private void ClearSendButton_Click(object sender, RoutedEventArgs e)
        {
            SendTextBox.Document.Blocks.Clear();
        }

        private void SendToAllButton_Click(object sender, RoutedEventArgs e)
        {
            if (tcpServerManager == null) return;
            string message = new TextRange(SendTextBox.Document.ContentStart, SendTextBox.Document.ContentEnd).Text.Trim();
            if (string.IsNullOrEmpty(message))
            {
                AppendTextToRecvTextBox("发送内容不能为空", "错误");
                return;
            }

            // 根据自动换行复选框状态处理消息
            if (AutoNewLineCheckBox.IsChecked == true)
            {
                // 如果勾选了自动换行，确保消息末尾有换行符
                if (!message.EndsWith("\r\n") && !message.EndsWith("\n"))
                {
                    message += "\r\n";
                }
            }
            else
            {
                // 如果未勾选自动换行，移除消息末尾的换行符
                message = message.TrimEnd('\r', '\n');
            }
            var selectedClients = ClientListView.SelectedItems.Cast<string>().ToList();
            if (selectedClients.Count == 0)
            {
                // 没有选中则对所有已连接客户端发送
                selectedClients = connectedClients;
            }
            if (selectedClients.Count == 0)
            {
                AppendTextToRecvTextBox("当前无可用客户端", "错误");
                return;
            }
            string selectedEncoding = EncodingComboBox.SelectedItem is ComboBoxItem item && item.Content != null
                ? item.Content.ToString() ?? string.Empty
                : string.Empty;
            Encoding encoding = GetEncodingByName(selectedEncoding);
            Task.Run(async () =>
            {
                bool allSent = true;
                foreach (var client in selectedClients)
                {
                    bool sent = await tcpServerManager.SendToClientAsync(client, message, encoding);
                    if (!sent) allSent = false;
                }
                Dispatcher.Invoke(() =>
                {
                    if (allSent)
                        AppendTextToRecvTextBox($"群发: {message}", "发>> ");
                    else
                        AppendTextToRecvTextBox("部分或全部发送失败", "错误");
                });
            });
        }

        private void SendToSelectedButton_Click(object sender, RoutedEventArgs e)
        {
            if (tcpServerManager == null) return;
            if (ClientListView.SelectedItems.Count != 1)
            {
                AppendTextToRecvTextBox("请只选择一个客户端", "错误");
                return;
            }
            string clientInfo = ClientListView.SelectedItem as string ?? string.Empty;
            string message = new TextRange(SendTextBox.Document.ContentStart, SendTextBox.Document.ContentEnd).Text.Trim();
            if (string.IsNullOrEmpty(message))
            {
                AppendTextToRecvTextBox("发送内容不能为空", "错误");
                return;
            }

            // 根据自动换行复选框状态处理消息
            if (AutoNewLineCheckBox.IsChecked == true)
            {
                // 如果勾选了自动换行，确保消息末尾有换行符
                if (!message.EndsWith("\r\n") && !message.EndsWith("\n"))
                {
                    message += "\r\n";
                }
            }
            else
            {
                // 如果未勾选自动换行，移除消息末尾的换行符
                message = message.TrimEnd('\r', '\n');
            }
            string selectedEncoding = EncodingComboBox.SelectedItem is ComboBoxItem item && item.Content != null
                ? item.Content.ToString() ?? string.Empty
                : string.Empty;
            Encoding encoding = GetEncodingByName(selectedEncoding);
            Task.Run(async () =>
            {
                bool sent = await tcpServerManager.SendToClientAsync(clientInfo, message, encoding);
                Dispatcher.Invoke(() =>
                {
                    if (sent)
                        AppendTextToRecvTextBox($"发给[{clientInfo}]: {message}", "发>> ");
                    else
                        AppendTextToRecvTextBox("发送失败", "错误");
                });
            });
        }

        private static Encoding GetEncodingByName(string encodingName)
        {
            return encodingName switch
            {
                "UTF-8" => Encoding.UTF8,
                "ASCII" => Encoding.ASCII,
                "GB2312" =>Encoding.GetEncoding("GB2312"),
                "GBK" => Encoding.GetEncoding("GBK"),
                "Unicode" => Encoding.Unicode,
                _ => Encoding.UTF8,
            };
        }
    }
}
